--I feel lazy so I won't use tables in tables
--CData Holds our client information; Data holds models and stuff including functions
local CDataPlayerIsScanner = {}
local CDataPlayerSENTStarted = {}
local CDataMarkers = {}
local CDataScanners = {}
local CDataLastScannerPos = {}
local CDataBomb = {}
local CDataBombLoaded = {}
DataFunctions = {} --GLOBAL!
local DataModels = {
	"models/combine_scanner.mdl" --models here please
	}
local DataPrecache = {
	"models/gibs/scanner_gib01.mdl",
	"models/gibs/scanner_gib02.mdl",
	"models/gibs/scanner_gib04.mdl",
	"models/gibs/scanner_gib05.mdl",
	"models/props_combine/combine_mine01.mdl"
	}
	
for k,v in pairs(DataPrecache) do
	util.PrecacheModel(v)
end
for k,v in pairs(DataModels) do
	util.PrecacheModel(v)
end

function DataFunctions.ScannerMove(ply)
	if not CDataScanners[ply]:IsValid() then
		DataFunctions.Reset(ply)
		return
	end
	local ang = ply:GetAimVector()
    local pos = CDataScanners[ply]:GetPos()+(CDataScanners[ply]:GetForward()*25)+(CDataScanners[ply]:GetUp()*-64)
	if ply:KeyDown(IN_FORWARD) then
		CDataMarkers[ply]:SetPos(pos+(ang*75));
		CDataScanners[ply]:Fire("ClearFollowTarget", "", "0")
		CDataScanners[ply]:Fire("SetFollowTarget", "marker_"..ply:UniqueID(), "0")
	end
	if ply:KeyPressed(IN_ATTACK) then
		if not CDataBombLoaded[ply] then
			local mine = ents.Create("sent_combine_mine")
			mine:SetPos(CDataScanners[ply]:GetPos()+(CDataScanners[ply]:GetUp()*-35))
			mine:Spawn()
			mine:Activate()
			local constraint = constraint.Weld(mine, CDataScanners[ply], 0, 0, 0)
			CDataBomb[ply] = mine
			CDataBombLoaded[ply] = true
		end
	end
	if ply:KeyPressed(IN_ATTACK2) then
		if CDataBombLoaded[ply] then
			CDataBomb[ply]:Arm()
			constraint.RemoveAll(CDataBomb[ply])
			CDataBomb[ply]:Arm()
			CDataBomb[ply] = nil
			CDataBombLoaded[ply] = false
		end
	end
	if ply:KeyPressed(IN_RELOAD) then
		DataFunctions.End(ply)
	end
end

function DataFunctions.Start(ply, SENT)
	if not ply:Alive() then return end
	if CDataPlayerIsScanner[ply] then return end
	if SENT > 0 then
		CDataPlayerSENTStarted[ply] = true
	else
		CDataPlayerSENTStarted[ply] = false
	end
	local pos = ply:GetPos()+Vector(0,0,10)
	local scanner = ents.Create("npc_cscanner")
	scanner:SetKeyValue("targetname", "pscanner_"..ply:UniqueID())
	scanner:SetKeyValue("spawnflags", "272")
	scanner:SetKeyValue("renderfx", "0")
	scanner:SetPos(pos)
	scanner:SetAngles(ply:GetAimVector())
	scanner:Spawn()
	CDataScanners[ply] = scanner;
	local marker = ents.Create("path_corner")
	marker:SetKeyValue("targetname", "marker_"..ply:UniqueID())
	marker:SetPos(ply:GetPos())
	marker:Spawn()
	local nucleaus = ents.Create("prop_physics")
	nucleaus:SetModel("models/props/cs_italy/orange.mdl")
	nucleaus:SetPos(ply:GetPos())
	nucleaus:Spawn()
	nucleaus:SetHealth(9999999999)
	nucleaus:SetParent(marker)
	CDataMarkers[ply] = marker
	DataFunctions.Spec(ply)
end

function DataFunctions.End(ply, cmd, args)
	if not CDataPlayerIsScanner[ply] then return end
	DataFunctions.Reset(ply)
end

function DataFunctions.Spec(ply)
	ply:Spectate(OBS_MODE_CHASE)
	ply:SpectateEntity(CDataScanners[ply])
	ply:StripWeapons()
	CDataScanners[ply]:Fire("SetFollowTarget" , "marker_"..ply:UniqueID(), 0 )
	CDataScanners[ply]:Fire("SetDistanceOverride", "64", 0)
	CDataScanners[ply]:Fire("addoutput" , "max_health "..ply:GetMaxHealth(), 0.01)
	CDataScanners[ply]:Fire("addoutput" , "health "..ply:Health(), 0.01)
	CDataPlayerIsScanner[ply] = ply
end

function DataFunctions.Reset(ply)
	ply:UnSpectate()
	if (not CDataPlayerSENTStarted[ply]) or (not CDataScanners[ply]:IsValid()) then
		ply:Kill()
	elseif CDataPlayerSENTStarted[ply] and CDataScanners[ply]:IsValid() then
		ply:SetPos(CDataScanners[ply]:GetPos())
		if CDataPlayerSENTStarted[ply] then
			local newscanner = ents.Create("pilotable_scanner_setup")
			newscanner:SetPos(CDataScanners[ply]:GetPos()+Vector(0,0,25))
			newscanner:SetAngles(CDataScanners[ply]:GetAngles())
			newscanner:Spawn()
			CDataScanners[ply]:Remove()
			if not newscanner:IsInWorld() then
				newscanner:Remove()
			end
		end
	end
	if CDataScanners[ply]:IsValid() then
		CDataScanners[ply]:SetHealth(0)
	end
	CDataMarkers[ply]:Remove()
	CDataMarkers[ply] = nil
	CDataPlayerIsScanner[ply] = nil
	CDataPlayerSENTStarted[ply] = nil
	CDataScanners[ply] = nil
	CDataLastScannerPos[ply] =  nil
	CDataBomb[ply] = nil
	CDataBombLoaded[ply] = nil
	
end

function DataFunctions.Think()
	for k,v in pairs(CDataPlayerIsScanner) do
		DataFunctions.ScannerMove(v)
	end
end

function DataFunctions.KillHook(vic, attack, weap)
	local player = false
	for k,v in pairs(CDataScanners) do
		if v == scanner then
			player = true
			break
		end
	end
	if not player then return end
	DataFunctions.Reset(lolwoot)
end

function DataFunctions.StartDumb(ply, cmd, args)
	DataFunctions.Start(ply, 0)
end

concommand.Add("Start_Piloting", DataFunctions.StartDumb)
concommand.Add("Stop_Piloting", DataFunctions.End)
hook.Add("Think", "PScanner_Think", DataFunctions.Think)
hook.Add("OnNPCKilled", "PScanner_NPCKill", DataFunctions.KillHook)

Msg("*************************\n");
Msg("*GM10 Pilotable Scanner:*\n");
Msg("*    By LuaPineapple    *\n");
Msg("*************************\n");